$.zhh.events.on("/employee/permission/role/", function(space, initial, extras) {

	var RES = { ids:{}, keys:{}, children:{}, parent:{} };

	var v = {};

	v.onCreateContinue = function(e) {
		var $sortIndex = e.form.find("input[textboxname=sortIndex]");
		var oldIndex = $sortIndex.xcall("getValue");
		e.form.form("disableValidation").form("clear");
		if (oldIndex) {
			$sortIndex.xcall("setValue", oldIndex * 1 + 1);
		}
	};
	
	v.onFilterExtraResources = function(e, extra, data) {
		// roleId:[resourceId]
		$.each(extra, function() {
			if (e.map[this.roleId]) {
				e.map[this.roleId].push(this.resourceId);
			} else {
				e.map[this.roleId] = [this.resourceId];
			}
		});
	};
	v.onDistributeAfterFillData = function(e) {
		var treegrid = e.popup.find(".x-treegrid.distribute");
		treegrid.xcall("clearSelections");
		batchSetCheckState(treegrid, extras.RoleResources.map[e.selected.id] || []);
		treegrid.xcall("options").dataReadonly = !!e.launcher.xcall("options").dataReadonly;
	};
	v.onDistributeAfterOpen = function(e) {
		var treegrid = e.popup.find(".x-treegrid.distribute");
		scrollToFirstCheckedPermission(treegrid);
	};
	v.onDistributeBeforeSubmit = function(e) {
		var treegrid = e.popup.find(".x-treegrid.distribute");
		var body = treegrid.xcall("getPanel").find(".datagrid-btable");
		e.form.find("input[type=hidden][name=resourceIds]").remove();
		var hidden = '<input type="hidden" name="{0}" value="{1}" />';
		body.find(".check-label.cascade-checked").each(function() {
			e.form.append($.zhh.format(hidden, "resourceIds", $(this).attr("node-id")));
		});
	};
	v.onResourceLoadFilter = function(data) {
		var list = $.fn.tree.parser.call(this, data);
		eachResource(list, function(self, parent) {
			RES.ids[this.id] = self;
			RES.keys[this.key] = self;
			RES.children[this.id] = self.children;
			RES.parent[this.id] = parent;
		});
		childrenToAttrs(list, "operates", "type", "MENU");
		return list;
	};
	// fn return false = break; return true = skip children;
	var eachResource = function(list, parent, fn) {
		if ($.isFunction(parent)) { fn = parent; parent = undefined; }
		$.each(list || [], function() {
			var result = fn && fn.call(this, this, parent);
			if (result === false) {
				return false;
			}
			if (result !== true && this.children) {
				eachResource(this.children, this, fn);
			}
		});
	};
	// 将符合条件的节点的children转换为一个属性
	var childrenToAttrs = function(list, attr, field, value) {
		eachResource(list, function() {
			if (this.children && this[field] == value) {
				this[attr] = this.children;
				delete this.children;
			}
		});
	};

	// 格式化字段
	v.format = {
		operatesToText: function(value, data) {
			if (data.operates) {
				var list = [];
				$.each(data.operates, function() {
					list.push('<span class="check-label" node-id="' + this.id + '">' + this.name + '</span>');
				});
				return list.join(" / ");
			}
		}
	};
	
	space.xui(v);

	space.find(".x-treegrid.distribute").xcall("getPanel")
	.on("click", ".datagrid-header .check-label", function() { // 全部
		var me = $(this);
		var treegrid = me.closest(".datagrid-view").children(".datagrid-f");
		if (treegrid.xcall("options").dataReadonly) { return; }
		var action = me.is(".cascade-checked") || me.is(".cascade-indeterminate") ? "uncheck" : "check";
		setCheckState(me, action);
		var roots = treegrid.xcall("getRoots");
		var box = me.closest(".datagrid-view").find(".datagrid-btable");
		$.each(roots, function() {
			var node = box.find(".datagrid-row[node-id=" + this.id + "]");
			eachSetCheckState(node, action);
		});
	})
	.on("click", ".tree-checkbox, .tree-title", function() { // 菜单权限
		var row = $(this).closest(".datagrid-row");
		var treegrid = row.closest(".datagrid-view").children(".datagrid-f");
		if (treegrid.xcall("options").dataReadonly) { return; }
		var action = row.is(".cascade-checked") || row.is(".cascade-indeterminate") ? "uncheck" : "check";
		// 向下传递
		eachSetCheckState(row, action);
		// 向上传递
		row.trigger("do-cascade", action);
	})
	.on("click", ".datagrid-row .check-label", function() { // 操作权限
		var me = $(this);
		var treegrid = me.closest(".datagrid-view").children(".datagrid-f");
		if (treegrid.xcall("options").dataReadonly) { return; }
		var isChecked = me.is(".cascade-checked");
		setCheckState(me, isChecked ? "uncheck" : "check");
		// 查询权限是其他权限的基础
		if (isChecked && isQueryPermission(me.attr("node-id"))) {
			me.siblings(".check-label.cascade-checked").each(function() {
				setCheckState($(this), "uncheck"); // 取消查询权限时将其他权限去掉
			});
		} else if (!isChecked && !isQueryPermission(me.attr("node-id"))) {
			me.siblings(".check-label:not(.cascade-checked)").each(function() {
				if (isQueryPermission($(this).attr("node-id"))) {
					setCheckState($(this), "check"); // 选其他权限时将查询权限选中
					return false;
				}
			});
		}
		// 向上传递
		var all = me.parent().children(".check-label");
		var checked = all.filter(".cascade-checked");
		var action = checked.length == 0 ? "uncheck" : checked.length == all.length ? "check" : "indeterminate";
		me.closest(".datagrid-row").trigger("do-cascade", action);
	})
	.on("do-cascade", ".datagrid-row", function(e, action) {
		var me = $(this);
		setCheckState(me, action);
		var all = me.parent().children(".datagrid-row");
		var indeterminate = all.filter(".cascade-indeterminate");
		var checked = all.filter(".cascade-checked");
		var action = "indeterminate";
		if (checked.length == 0 && indeterminate.length == 0) {
			action = "uncheck";
		} else if (checked.length == all.length) {
			action = "check";
		}
		// 向上传递
		var id = me.attr("node-id");
		var box = me.closest(".datagrid-view");
		if (RES.parent[id]) {
			var pid = RES.parent[id].id;
			var parent = box.find(".datagrid-row[node-id=" + pid + "]");
			parent.trigger("do-cascade", action);
		} else { // 已到顶级, 向上传递到全选按钮
			var root = box.find(".datagrid-header .check-label");
			setCheckState(root, action);
		}
	});
	var isQueryPermission = function(resourceId) {
		var res = RES.ids[resourceId];
		if (res.key.endsWith(":query")) {
			var parent = RES.parent[resourceId];
			if (res.key == parent.key + ":query") {
				return true;
			}
		}
		return false;
	};
	var eachSetCheckState = function(row, action) {
		// action = uncheck|check, 不能是indeterminate
		if (action == "indeterminate") { return; }
		// 向下传递
		var box = row.closest(".datagrid-view");
		var id = row.attr("node-id");
		eachResource([RES.ids[id]], function() {
			var node = box.find(".datagrid-row[node-id=" + this.id + "]");
			var isChecked = node.is(".cascade-checked");
			var isUncheck = !node.is(".cascade-checked") && !node.is(".cascade-indeterminate");
			if (action == "check" && isChecked || action == "uncheck" && isUncheck) {
				return true;
			}
			setCheckState(node, action);
			if (!this.children) { // 叶子节点
				setCheckState(node.find(".check-label"), action);
			}
		});
	};
	var setCheckState = function(node, action) {
		if (action == "check") { // 子节点已全部选中
			node.removeClass("cascade-indeterminate").addClass("cascade-checked");
		} else if (action == "uncheck") { // 一个子节点也没选中
			node.removeClass("cascade-checked cascade-indeterminate");
		} else if (action == "indeterminate") { // 子节点半选定
			node.removeClass("cascade-checked").addClass("cascade-indeterminate");
		}
	};
	var batchSetCheckState = function(treegrid, list) {
		// list=选中节点, 只有最末级的OPERATE, 没有菜单数据
		var map = {};
		$.each(list || [], function(i, v) {
			map[v] = v;
		});
		var body = treegrid.xcall("getPanel").find(".datagrid-btable");
		// 先全部置为未选中
		var all = treegrid.xcall("getPanel").find(".datagrid-header .check-label");
		setCheckState(all, "uncheck");
		body.find(".datagrid-row, .check-label").each(function() {
			setCheckState($(this), "uncheck");
		});
		if (list && list.length) {
			// 逐一设置操作权限的选中状态
			body.find(".check-label").each(function() {
				var me = $(this);
				var id = me.attr("node-id");
				if (map[id]) {
					setCheckState(me, "check");
				}
			});
			// 按行向上传递选中状态
			body.find(".datagrid-row").each(function() {
				var row = $(this);
				var all = row.find(".check-label");
				var checked = all.filter(".cascade-checked");
				if (checked.length > 0) {
					var action = checked.length == all.length ? "check" : "indeterminate";
					row.trigger("do-cascade", action);
				}
			});
		}
	};
	var scrollToFirstCheckedPermission = function(treegrid) {
		var body = treegrid.xcall("getPanel").find(".datagrid-btable");
		var first = body.find(".check-label.cascade-checked:first");
		var row;
		if (first.length) { 
			row = first.closest(".datagrid-row")
		} else {
			row = body.find(".datagrid-row:first");
		}
		if (row.length == 0) { return; }
		treegrid.xcall("scrollTo", row.attr("node-id"));
	};
});